#include <SPIwiring.h>
#include <delay.h>
#include <stdio.h>
#include <string.h>
#include <lcd.h>
#include <gpdr_eeprom.h>

#define CR 0x0D
#define BUF_LEN 2048
#define PACKET_SIZE 1920 // if mode == 1 (if mode == 0, then packet size is buffer volume)

flash char setup_file[10] = "SETUP.TXT";
flash char time_file[9] = "TIME.TXT";
flash char tf2rtc[7] = {2, 1, 0, 3, 4, 5, 6}; // map hhmmssDDddmmyy to ssmmhhDDddmmyy

extern volatile unsigned char vini_buffer_full;
extern unsigned long int sample_period;
extern unsigned char sample_table;
extern unsigned int sample_period_table[1440];
extern long int ymdh0;
char buffer[BUF_LEN];
unsigned int rx_index = 0;
unsigned int tx_index = 0;
unsigned int tx_buffr = 0;
extern volatile unsigned char full_messages;
extern volatile unsigned char lcd_present;
extern volatile unsigned char gps_present;
extern volatile unsigned char sim_present;
unsigned char disk_present = 1;

void putstr(char *str)
{
char k;
while (k = *str++)
    {
    putchar(k);
    }
}

void putstrf(char flash *str)
{
char k;
while (k = *str++)
    {
    putchar(k);
    }
}

char rx2buffer(unsigned char mode)
{
char r_value;

r_value = getchar();

if (mode == 1)
    {
    char2buffer(r_value);
    }
    
return r_value;
}

void char2buffer(char data)
{
    buffer[rx_index++] = data;
    rx_index &= BUF_LEN-1;
    tx_buffr++;

if (tx_buffr < PACKET_SIZE) 
    {
//    buffer[rx_index++] = data;
//    rx_index &= BUF_LEN-1;
//    tx_buffr++;

//    if (tx_buffr == PACKET_SIZE)
//        { 
//        buffer[rx_index++] = 13; // insert CR when buffer full
//        rx_index &= BUF_LEN-1;
//        tx_buffr++;
//        }
    }
    
else
    {
    vini_buffer_full = 1; // handle buffer overrun
    }
}

void str2buffer(char *str)
{
char k;
while (k = *str++)
    {
    char2buffer(k);
    }
}

void strf2buffer(char flash *str)
{
char k;
while (k = *str++)
    {
    char2buffer(k);
    }
}

void rtc2ymdhms(unsigned char *rtc_msg, unsigned char *ymdhms)
{
ymdhms[0] = 10*(rtc_msg[6]>>4) + (rtc_msg[6]&0x0F);
ymdhms[1] = 10*(rtc_msg[5]>>4) + (rtc_msg[5]&0x0F);
ymdhms[2] = 10*(rtc_msg[4]>>4) + (rtc_msg[4]&0x0F);
ymdhms[3] = 10*(rtc_msg[2]>>4) + (rtc_msg[2]&0x0F);
ymdhms[4] = 10*(rtc_msg[1]>>4) + (rtc_msg[1]&0x0F);
ymdhms[5] = 10*(rtc_msg[0]>>4) + (rtc_msg[0]&0x0F);
}

void rtc2buffer(void)
{
unsigned char rtc_msg[7];
unsigned char i;

rtc_read(rtc_msg);

for (i=0;i<7;i++)
    {
    char2buffer(rtc_msg[i]);
    }
}

unsigned char wait4prompt()
{
unsigned char prompt_received = 0;

do
    {
    if (wait4message() == 1)
        {
        prompt_received = 1;
        }

    else
        {
        prompt_received = 0;
        }
    } while ((spi_status()&0x02) == 0);

return prompt_received; 
}

unsigned char wait4message()
{
unsigned char message[25];
unsigned char msg = 0;

//msg = 1;  // "D:\\>"
//msg = 2;  // "No Disk"
//msg = 3;  // "Bad Command"
//msg = 4;  // "Command Failed"
//msg = 5;  // "Disk Full"
//msg = 6;  // "Invalid"
//msg = 7;  // "Read Only"
//msg = 8;  // "File Open"
//msg = 9;  // "Dir Not Empty"
//msg = 10; // "Filename Invalid"
//msg = 11; // "No Upgrade"
//msg = 12; // "Device Detected P1"
//msg = 13; // "Device Removed P1"
//msg = 14; // "Device Detected P2"
//msg = 15; // "Device Removed P2"
//msg = 16; // "Slave Enabled"
//msg = 17; // "Slave Disabled"
//msg = 18; // "Ver 03.68VDAPF On-Line:"

//msg = 1;  // "D:\\>"
//msg = 3;  // "Bad Command"
//msg = 4;  // "Command Failed"
//msg = 12; // "Device Detected P1"
//msg = 14; // "Device Detected P2"
//msg = 13; // "Device Removed P1"
//msg = 15; // "Device Removed P2"
//msg = 9;  // "Dir Not Empty"
//msg = 5;  // "Disk Full"
//msg = 8;  // "File Open"
//msg = 10; // "Filename Invalid"
//msg = 6;  // "Invalid"
//msg = 2;  // "No Disk"
//msg = 11; // "No Upgrade"
//msg = 7;  // "Read Only"
//msg = 16; // "Slave Enabled"
//msg = 17; // "Slave Disabled"
//msg = 18; // "Ver 03.68VDAPF On-Line:"

scanf("%s", message);

if (strncmpf(message, "D:\\>", 4) == 0)
    {
    msg = 1;
    if (full_messages == 1)
        {
        strf2buffer("D:\\>\r");
        }
    }

else if (strncmpf(message, "Bad", 3) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Command", 7) == 0)
        {
        msg = 3;
        if (full_messages == 1)
            {
            strf2buffer("Bad Command\r");
            }
        }
    }

else if (strncmpf(message, "Command", 7) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Failed", 6) == 0)
        {
        msg = 4;
        if (full_messages == 1)
            {
            strf2buffer("Command Failed\r");
            }
        }
    }

else if (strncmpf(message, "Device", 6) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Detected", 8) == 0)
        {
        scanf("%s", message);
        if (strncmpf(message, "P1", 2) == 0)
            {
            msg = 12;
            if (full_messages == 1)
                {
                strf2buffer("Device Detected P1\r");
                }
            }
        
        else if (strncmpf(message, "P2", 2) == 0)
            {
            msg = 14;
            if (full_messages == 1)
                {
                strf2buffer("Device Detected P2\r");
                }
            
            disk_present = 1;
            }
        }

    else if (strncmpf(message, "Removed", 7) == 0)
        {
        scanf("%s", message);
        if (strncmpf(message, "P1", 2) == 0)
            {
            msg = 13;
            if (full_messages == 1)
                {
                strf2buffer("Device Removed P1\r");
                }
            }
        
        else if (strncmpf(message, "P2", 2) == 0)
            {
            msg = 15;
            if (full_messages == 1)
                {
                strf2buffer("Device Removed P2\r");
                }
            
            disk_present = 0;
            }
        }
    }

else if (strncmpf(message, "Dir", 3) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Not", 3) == 0)
        {
        scanf("%s", message);
        if (strncmpf(message, "Empty", 5) == 0)
            {
            msg = 9;
            if (full_messages == 1)
                {
                strf2buffer("Dir Not Empty\r");
                }
            }
        }
    }

else if (strncmpf(message, "Disk", 4) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Full", 4) == 0)
        {
        msg = 5;
        if (full_messages == 1)
            {
            strf2buffer("Disk Full\r");
            }
        }
    }

else if (strncmpf(message, "File", 4) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Open", 4) == 0)
        {
        msg = 8;
        if (full_messages == 1)
            {
            strf2buffer("File Open\r");
            }
        }
    }

else if (strncmpf(message, "Filename", 8) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Invalid", 7) == 0)
        {
        msg = 10;
        if (full_messages == 1)
            {
            strf2buffer("Filename Invalid\r");
            }
        }
    }

else if (strncmpf(message, "Invalid", 7) == 0)
    {
    msg = 6;
    if (full_messages == 1)
        {
        strf2buffer("Invalid\r");
        }
    }

else if (strncmpf(message, "No", 2) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Disk", 4) == 0)
        {
        msg = 2;
        if (full_messages == 1)
            {
            strf2buffer("No Disk\r");
            strf2buffer("Transmit Buffer: ");
            sprintf(message, "%u", tx_buffr);
            str2buffer(message);
            strf2buffer("\r");
            }
        }

    else if (strncmpf(message, "Upgrade", 7) == 0)
        {
        msg = 11;
        if (full_messages == 1)
            {
            strf2buffer("No Upgrade\r");
            }
        }
    }

else if (strncmpf(message, "Read", 4) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Only", 4) == 0)
        {
        msg = 7;
        if (full_messages == 1)
            {
            strf2buffer("Read Only\r");
            }
        }
    }

else if (strncmpf(message, "Slave", 5) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "Enabled", 7) == 0)
        {
        msg = 16;
        if (full_messages == 1)
            {
            strf2buffer("Slave Enabled\r");
            }
        }

    else if (strncmpf(message, "Disabled", 8) == 0)
        {
        msg = 17;
        if (full_messages == 1)
            {
            strf2buffer("Slave Disabled\r");
            }
        }
    }

else if (strncmpf(message, "Ver", 3) == 0)
    {
    scanf("%s", message);
    if (strncmpf(message, "03.68VDAPF", 10) == 0)
        {
        scanf("%s", message);
        if (strncmpf(message, "On-Line:", 8) == 0)
            {
            msg = 18;
            if (full_messages == 1)
                {
                strf2buffer("Ver 03.68VDAPF On-Line:\r");
                }
            }
        }
    }

if (msg == 0)
    {
    if (full_messages == 1)
        {
        strf2buffer("Message Fragment: ");
        str2buffer(message);
        strf2buffer("\r");
        }
    }

return msg; 
}

void open_file4write(char *fname, unsigned char time_tag)
{
unsigned char rtc_msg[7];
unsigned char ymdhms[6];
char msg[50];

if (disk_present == 1)
    {
    rtc_read(rtc_msg);
    rtc2ymdhms(rtc_msg, ymdhms);

    // 9:15  year      0-127 0=1980 127=2107
    // 5:8   month     1-12  1=january 12=december
    // 0:4   day       1-31  1=first day of month
    // 11:15 hour      0-23  24 hour clock
    // 5:10  minute    0-59
    // 0:4   seconds/2 0-29  0=0 seconds 29=58 seconds

    putstrf("OPW ");
    putstr(fname);
    putchar(32);
    putchar((((20 + ymdhms[0])<<9)|(ymdhms[1]<<5)|ymdhms[2])>>8);
    putchar((((20 + ymdhms[0])<<9)|(ymdhms[1]<<5)|ymdhms[2]));
    putchar(((ymdhms[3]<<11)|(ymdhms[4]<<5)|ymdhms[5]>>1)>>8);
    putchar(((ymdhms[3]<<11)|(ymdhms[4]<<5)|ymdhms[5]>>1));
    putchar(CR);

    if (full_messages == 1)
        {
        strf2buffer("Open File for Write\r");
        }
    
    if (time_tag == 1)
        {
        sprintf(msg, "YY%02i MM%02i DD%02i %02i:%02i:%02i\r", ymdhms[0], ymdhms[1], ymdhms[2], ymdhms[3], ymdhms[4], ymdhms[5]);
        str2buffer(msg);
        }

    wait4prompt();
    }
}

void write_buffer2file(unsigned char mode)
{
unsigned int tx_end_index, packet_size;

#asm("cli")

if (disk_present == 1)
    {
    if (full_messages == 1)
        {
        strf2buffer("Write Buffer to File\r");
        }

    packet_size = mode?PACKET_SIZE:tx_buffr;

    if (tx_buffr > 0)
        {
        tx_end_index = tx_index + packet_size;
        tx_end_index &= BUF_LEN-1;

        putstrf("WRF ");
        putchar(0); // high word of 32bit numvalue is 0
        putchar(0);
        putchar(packet_size>>8);
        putchar(packet_size);
        putchar(CR);

        while (tx_index != tx_end_index)
            {
            putchar(buffer[tx_index]);
            tx_index++;
            tx_index &= BUF_LEN-1;
            tx_buffr--;
            }

        wait4prompt();
  
        if (full_messages == 1)
            {
            strf2buffer("Sending Buffer to File\r");
            }

        putchar(CR);
    
#asm("sei")

        wait4prompt();
        }
    }
}

void check_buffer(void)
{
if (tx_buffr >= PACKET_SIZE)
    {
    write_buffer2file(1);
    }
}

void close_file(flash char *fname)
{
if (disk_present == 1)
    {
    putstrf("CLF ");
    putstrf(fname);
    putchar(CR);

    if (full_messages == 1)
        {
        strf2buffer("Closing File\r");
        }

    wait4prompt();
    }
}

void close_file_nf(char *fname)
{
if (disk_present == 1)
    {
    putstrf("CLF ");
    putstr(fname);
    putchar(CR);

    if (full_messages == 1)
        {
        strf2buffer("Closing File\r");
        }

    wait4prompt();
    }
}

void rename_file(flash char *fname, flash char *fname_new)
{
if (disk_present == 1)
    {
    putstrf("REN ");
    putstrf(fname);
    putchar(32);
    putstrf(fname_new);
    putchar(CR);

    if (full_messages == 1)
        {
        strf2buffer("Renaming File\r");
        }

    wait4prompt();
    }
}

void open_file4read(flash char *fname)
{
putstrf("RD ");
putstrf(fname);
putchar(CR);
}

void read_setup_from_file(void)
{
unsigned char i, c;
unsigned char rtc_msg[7];
unsigned char ymdhms[6];
unsigned char device[20];
unsigned char usb_device[16];
long int ymdh;

for (i=0;i<8;i++) // "Device: " not robust to syntax errors . . .
    {
    rx2buffer(1);
    }

i = 0;

do
    {
    usb_device[i] = rx2buffer(1);
    } while (usb_device[i++] != 13);

usb_device[--i] = 0;

rx2buffer(1);

device_name(device);

if (device[0] == 255)
    {
    store_device_name(usb_device);
    strf2buffer("Christening: ");
    str2buffer(usb_device);
    strf2buffer("\r");
    }

else if (device[0] == usb_device[0])
    {
    strf2buffer("Confirmed: ");
    str2buffer(device);
    strf2buffer("\r");
    }
    
else
    {
    strf2buffer("Already Christened: ");
    str2buffer(device);
    strf2buffer("\r");
    }

for (i=0;i<10;i++) // "Messages: " not robust to syntax errors . . .
    {
    rx2buffer(1);
    }

full_messages = (rx2buffer(1) - 48);
rx2buffer(1);
rx2buffer(1);

for (i=0;i<5;i++) // "LCD: " not robust to syntax errors . . .
    {
    rx2buffer(1);
    }

lcd_present = (rx2buffer(1) - 48);

if (lcd_present == 2) // "GPS: 2
    {
    lcd_present = 0;
    gps_present = 1;
    }

else if (lcd_present == 4) // "SIM: 4
    {
    lcd_present = 0;
    sim_present = 1;
    }

rx2buffer(1);
rx2buffer(1);

rtc_read(rtc_msg);
rtc2ymdhms(rtc_msg, ymdhms);
ymdh0 = (long int)ymdhms[0]*12*31*24 + (long int)ymdhms[1]*31*24 + (long int)ymdhms[2]*24;

for (i=0;i<8;i++) // "Period: " not robust to syntax errors . . .
    {
    rx2buffer(1);
    }

c = rx2buffer(1);

if (c == 'T') // table of values
    {
    for (i=0;i<4;i++) // "Table" not robust to syntax errors . . .
        {
        rx2buffer(1);
        }
        
    sample_table = 1;
        
    rx2buffer(0); // carriage return

    do
        {
//        char2buffer(13);

//        rx2buffer(1); // line feed
        rx2buffer(0); // line feed
        
//        ymdh = (((long int)rx2buffer(1) - 48)*10 + ((long int)rx2buffer(1) - 48))*12*31*24 + (((long int)rx2buffer(1) - 48)*10 + ((long int)rx2buffer(1) - 48))*31*24 + (((long int)rx2buffer(1) - 48)*10 + ((long int)rx2buffer(1) - 48))*24 + ((long int)rx2buffer(1) - 48)*10 + (long int)rx2buffer(1) - 48 - ymdh0;
        ymdh = (((long int)rx2buffer(0) - 48)*10 + ((long int)rx2buffer(0) - 48))*12*31*24 + (((long int)rx2buffer(0) - 48)*10 + ((long int)rx2buffer(0) - 48))*31*24 + (((long int)rx2buffer(0) - 48)*10 + ((long int)rx2buffer(0) - 48))*24 + ((long int)rx2buffer(0) - 48)*10 + (long int)rx2buffer(0) - 48 - ymdh0;

//        rx2buffer(1); // space
        rx2buffer(0); // space
        
        if (ymdh >= 0)
            {
//            sample_period_table[ymdh] = ((unsigned int)rx2buffer(1) - 48)*10000 + ((unsigned int)rx2buffer(1) - 48)*1000 + ((unsigned int)rx2buffer(1) - 48)*100 + ((unsigned int)rx2buffer(1) - 48)*10 + ((unsigned int)rx2buffer(1) - 48);
            sample_period_table[ymdh] = ((unsigned int)rx2buffer(0) - 48)*10000 + ((unsigned int)rx2buffer(0) - 48)*1000 + ((unsigned int)rx2buffer(0) - 48)*100 + ((unsigned int)rx2buffer(0) - 48)*10 + ((unsigned int)rx2buffer(0) - 48);
            }
            
        else
            {
//            rx2buffer(1);
//            rx2buffer(1);
//            rx2buffer(1);
//            rx2buffer(1);
//            rx2buffer(1);
//            strf2buffer(" expired");
            rx2buffer(0);
            rx2buffer(0);
            rx2buffer(0);
            rx2buffer(0);
            rx2buffer(0);
            }
        
        } while (rx2buffer(0) == 13);

    char2buffer(13);
    char2buffer(10);

    sample_period = (unsigned long int)sample_period_table[(unsigned long int)ymdhms[0]*12*31*24 + (unsigned long int)ymdhms[1]*31*24 + (unsigned long int)ymdhms[2]*24 + (unsigned long int)ymdhms[3] - ymdh0];

    if ((sample_period < 5) || (sample_period > 3600))
        {
        sample_period = 60;
        }
    }
    
else
    {
    sample_period = ((unsigned long int)c - 48)*10000 + ((unsigned long int)rx2buffer(1) - 48)*1000 + ((unsigned long int)rx2buffer(1) - 48)*100 + ((unsigned long int)rx2buffer(1) - 48)*10 + ((unsigned long int)rx2buffer(1) - 48);
    rx2buffer(1);
    }

wait4prompt();
}

void read_time_from_file(unsigned char *rtc_msg)
{
unsigned char i;

for (i=0;i<7;i++)
    {
    rtc_msg[tf2rtc[i]] = (rx2buffer(1) - 48)<<4 | (rx2buffer(1) - 48);
    rx2buffer(1);
    }

wait4prompt();
}

void get_setup_from_file(void)
{
open_file4read(setup_file);
read_setup_from_file();
close_file(setup_file);
}

void set_time_from_file(void)
{
unsigned char rtc_msg[7];
open_file4read(time_file);
read_time_from_file(rtc_msg);
rtc_write(rtc_msg, 1);
close_file(time_file);
rename_file(time_file, "baktime.txt");
}

void check4setup_file(void)
{
unsigned char i;

putstrf("DIR SETUP.TXT");
putchar(CR);
getchar();

if (getchar() == 'S')
    {
    while (getchar() != 13)
        {
        }

    strf2buffer("Get Setup From File\r");
    wait4prompt();
    get_setup_from_file();
    }
else
    {
    for (i=0;i<14;i++) // remove "Command Failed\r"
        {
        getchar();
        }

    if (full_messages == 1)
        {
        strf2buffer("Use Default Setup\r");
        strf2buffer("D:\\>\r");
        }
    }
}

void check4time_file(void)
{
unsigned char i;

putstrf("DIR TIME.TXT");
putchar(CR);
getchar();

if (getchar() == 'T')
    {
    while (getchar() != 13)
        {
        }

    strf2buffer("Set Time From File\r");
    wait4prompt();
    set_time_from_file();
    }

else
    {
    for (i=0;i<14;i++) // remove "Command Failed\r"
        {
        getchar();
        }

    if (full_messages == 1)
        {
        strf2buffer("No Time From File\r");
        strf2buffer("D:\\>\r");
        }
    }

//putstrf("DIR");
//putchar(CR);
//wait4prompt();
}

void suspend_monitor(void)
{
putstrf("SUM");
putchar(CR);

if (full_messages == 1)
    {
    strf2buffer("Suspending Monitor\r");
    }
}

void suspend_disk(void)
{
putstrf("SUD");
putchar(CR);

if (full_messages == 1)
    {
    strf2buffer("Suspending Disk\r");
    }

wait4prompt();
}

void wake_monitor(void)
{
putchar(CR);

if (full_messages == 1)
    {
    strf2buffer("Waking Monitor\r");
    }

wait4prompt();
}

void wake_disk(void)
{
putstrf("WKD");
putchar(CR);

if (full_messages == 1)
    {
    strf2buffer("Waking Disk\r");
    }

wait4prompt();
}

#ifndef _DEBUG_TERMINAL_IO_
#define _ALTERNATE_PUTCHAR_
// Write a character to the SPI Transmitter
#pragma used+
void putchar(char c)
{
char SDI7, SDI6, SDI5, SDI4, SDI3, SDI2, SDI1, SDI0;
char OUT7, OUT6, OUT5, OUT4, OUT3, OUT2, OUT1, OUT0;
char result, status;

// SETUP //

SDI0 = c & 1;
c >>= 1;
SDI1 = c & 1;
c >>= 1;
SDI2 = c & 1;
c >>= 1;
SDI3 = c & 1;
c >>= 1;
SDI4 = c & 1;
c >>= 1;
SDI5 = c & 1;
c >>= 1;
SDI6 = c & 1;
c >>= 1;
SDI7 = c & 1;

// SEND AND RECEIVE //

#asm("cli")

do
    {
    PORT.SCK = 1;
    PORT.SCK = 0;

    PORT.CS = 1;
    PORT.MOSI = 1; // 1
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT0 = MI;
    PORT.MOSI = 0; // 0
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT0 = MI;
    PORT.MOSI = 0; // 0
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT7 = MI;
    PORT.MOSI = SDI7; // MSB
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT6 = MI;
    PORT.MOSI = SDI6;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT5 = MI;
    PORT.MOSI = SDI5;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT4 = MI;
    PORT.MOSI = SDI4;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT3 = MI;
    PORT.MOSI = SDI3;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT2 = MI;
    PORT.MOSI = SDI2;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT1 = MI;
    PORT.MOSI = SDI1;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT0 = MI;
    PORT.MOSI = SDI0; // LSB
    PORT.SCK = 1;
    PORT.SCK = 0;

    status = MI;
    PORT.MOSI = 0; // 0
    PORT.SCK = 1;
    PORT.SCK = 0;

    PORT.CS = 0;
    PORT.SCK = 1;
    PORT.SCK = 0;

// PROCESS //

    result = OUT7<<7 | OUT6<<6 | OUT5<<5 | OUT4<<4 | OUT3<<3 | OUT2<<2 | OUT1<<1 | OUT0<<0;

    } while (status == 1);

#asm("sei")
}
#pragma used-
#endif

#ifndef _DEBUG_TERMINAL_IO_
#define _ALTERNATE_GETCHAR_
// Get a character from the SPI Receiver
#pragma used+
char getchar(void)
{
char OUT7, OUT6, OUT5, OUT4, OUT3, OUT2, OUT1, OUT0;
char result, status;

#asm("cli")

do
    {
    PORT.SCK = 1;
    PORT.SCK = 0;
    PORT.CS = 1;

    PORT.MOSI = 1; // 1
    PORT.SCK = 1;
    PORT.SCK = 0;

    PORT.MOSI = 1; // 1
    PORT.SCK = 1;
    PORT.SCK = 0;

    PORT.MOSI = 0; // 0
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT7 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT6 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT5 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT4 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT3 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT2 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT1 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT0 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    status = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    PORT.CS = 0;
    PORT.SCK = 1;
    PORT.SCK = 0;

// PROCESS //

    result = OUT7<<7 | OUT6<<6 | OUT5<<5 | OUT4<<4 | OUT3<<3 | OUT2<<2 | OUT1<<1 | OUT0<<0;

    } while (status == 1);

#asm("sei")

return result;
}
#pragma used-
#endif

char spi_status(void)
{
char OUT7, OUT6, OUT5, OUT4, OUT3, OUT2, OUT1, OUT0;
char result, status;

#asm("cli")

do
    {
    PORT.SCK = 1;
    PORT.SCK = 0;
    PORT.CS = 1;

    PORT.MOSI = 1; // 1
    PORT.SCK = 1;
    PORT.SCK = 0;

    PORT.MOSI = 1; // 1
    PORT.SCK = 1;
    PORT.SCK = 0;

    PORT.MOSI = 1; // 1
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT7 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT6 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT5 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT4 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT3 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT2 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT1 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    OUT0 = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    status = MI;
    PORT.SCK = 1;
    PORT.SCK = 0;

    PORT.CS = 0;
    PORT.SCK = 1;
    PORT.SCK = 0;

// PROCESS //

    result = OUT7<<7 | OUT6<<6 | OUT5<<5 | OUT4<<4 | OUT3<<3 | OUT2<<2 | OUT1<<1 | OUT0<<0;

    } while (status == 1);

#asm("sei")

return result;
}


void display_value(unsigned char c){
    unsigned char display = 0;
    display = c/100+48;
    
    if (lcd_present == 1)
        {
        lcd_putchar(display);
        }
        
    char2buffer(display);      
    c = c%100;
    display = c/10+48;
    
    if (lcd_present == 1)
        {
        lcd_putchar(display);
        }
        
    char2buffer(display);
    c = c%10+48;
    
    if (lcd_present == 1)
        {
        lcd_putchar(c);
        }
        
    char2buffer(c);
}
